package structs.term.dept.course;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import structs.term.dept.Department;
import structs.term.dept.course.section.Instructor;
import structs.term.dept.course.section.Section;
import exception.InvalidNameException;

/**
 * Represents a single course within a department.
 * Contains references to each section of this course.
 * @author SJP
 *
 */
public class Course implements Comparable<Course>{
	
	/**
	 * Department reference
	 */
	private Department dept;
	
	/**
	 * Course number
	 */
	private int number;
	
	/**
	 * Course name
	 */
	private String name;
	
	/**
	 * Sections of this course
	 */
	private Map<String, Section> sections;
	
	//private static Connection con;
	
	/**
	 * Create a new course
	 * @param i course number
	 * @param n course name
	 */
	public Course(Department d, int i, String n) {
		dept = d;
		number = i;
		name = n;
		sections = new HashMap<String,Section>();
	}
	
	/**
	 * MUST BE CALLED BEFORE CREATING ANY COURSE OBJECTS.
	 * Saves a reference to the current db connection and initializes
	 * the prepared statements to select, insert, or update a book in the db.
	 * @param c
	 * @throws SQLException
	 */
	/*public static void setCon(Connection c) throws SQLException {
		con = c;
	}*/
	
	/**
	 * @return the course number
	 */
	public int getNumber() {return number;}
	
	/**
	 * @return the course name
	 */
	public String getName() {return name;}
	
	/**
	 * Returns the section with name n
	 * @param n
	 * @return
	 */
	public Section getSection(String n) {
		if (sections.containsKey(n))
			return sections.get(n);
		else
			return null;
	}
	
	/**
	 * @return the dept
	 */
	public Department getDept() {
		return dept;
	}

	public Section addSection(String sec, Instructor inst, int sec_id) {
		if (sections.containsKey(sec))
			return sections.get(sec);
		else {
			Section s = new Section(dept,this,sec,inst,sec_id);
			sections.put(sec,s);
			
			return s;
		}
	}
	
	/**
	 * Creates a new section of this course if there is
	 * not already one with the given id.
	 * @param id section id
	 * @param inst section instructor
	 * @return
	 */
	public Section addSection(String id, Instructor inst) throws InvalidNameException{
		if (sections.containsKey(id))
			throw new InvalidNameException("Add Section: id \""+id+"\" already exists.");
		else {
			Section s =  new Section(dept,this,id,inst);
			sections.put(id,s);
			
			return s;
		}
	}
	
	/**
	 * Creates a new section of this course if there is
	 * not already one with the given id.
	 * @param s section
	 * @param inst section instructor
	 * @return
	 */
	public Section addSection(Section s) throws InvalidNameException{
		if (sections.containsValue(s))
			throw new InvalidNameException("Add Section: section \""+s.getID()+"\" already exists.");
		else {
			sections.put(s.getID(), s);
			return s;
		}
	}
	
	public Map<String, Section> getSections() {
		return sections;
	}
	
	public Collection<Section> getSectionsOrdered() {
		ArrayList<Section> out = new ArrayList<Section>(getSections().values());
		Collections.sort(out);
		
		return out;
	}
	
	/**
	 * TODO
	 */
	public void termRollover() {}
	
	@Override
	public String toString() {return String.valueOf(number);}

	@Override
	public int compareTo(Course o) {
		int myNum = getNumber(), yourNum = o.getNumber();
		return Integer.compare(myNum, yourNum);
	}
}
